﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Security.Cryptography;
using System.Data.SqlClient;

namespace GestorDeFlotasDesktop.Login
{
    public partial class Login : Form
    {
        #region Properties
        private Boolean isValidated = false;
        public static MainForm mainForm;
        public static List<int> permisosList = new List<int>();
        #endregion

        #region Public
        public Login()
        {
            InitializeComponent();
        }
        #endregion

        #region Events
        private void login_button_Click(Object sender, EventArgs e)
        {
            //TODO: agregar validacion de user&pass
            isValidated = validateUser(user.Text, passwd.Text);
            if (isValidated)
            {
                mainForm = new MainForm(this);
                mainForm.Show();
            }
            else
            {
                MessageBox.Show("La combinación de usuario/contraseña es erronea, o usuario no habilitado", "Error de Login");
                foreach (Control ctrl in this.Controls)
                {
                    if (ctrl is TextBox)
                    {
                        ((TextBox)ctrl).Clear();
                    }
                }
            }
        }
        #endregion

        private Boolean validateUser(String user, String passwd)
        {
            bool return_value = false;
            if (String.IsNullOrEmpty(user) || String.IsNullOrEmpty(passwd))
            {
                return return_value;
            }
            using (SqlConnection con = Modelo.Modelo.createConnection())
            {
                try
                {
                    //Validate user
                    Modelo.Modelo.openConnection(con);
                    SqlCommand validate_user = new SqlCommand(Modelo.SqlQueries.getUserInfo(user), con);
                    SqlDataReader reader = validate_user.ExecuteReader();
                    //If users exists
                    if (reader.FieldCount > 0)
                    {
                        reader.Read();
                        string password = reader.GetString(1);
                        int login_failed = Convert.ToInt32(reader.GetDecimal(2));
                        bool habilitado = reader.GetBoolean(3);
                        //Validated passwd and enabled
                        if (password.Equals(getSHA256(passwd)) && habilitado)
                        {
                            SqlConnection con2 = Modelo.Modelo.createConnection();
                            Modelo.Modelo.openConnection(con2);
                            SqlCommand reset_fails = new SqlCommand(Modelo.SqlQueries.resetLoginFails(user), con2);
                            reset_fails.ExecuteNonQuery();
                            Modelo.Modelo.closeConnection(con2);
                            getPermissions(user);
                            return_value = true;
                        }
                        //User exists, but wrong passwd or not enabled
                        else
                        {
                            if (login_failed < 3)
                            {

                                SqlConnection con4 = Modelo.Modelo.createConnection();
                                Modelo.Modelo.openConnection(con4);
                                SqlCommand inc_login_fail = new SqlCommand(Modelo.SqlQueries.incUserLoginFailed(user, login_failed + 1), con4);
                                inc_login_fail.ExecuteNonQuery();
                                Modelo.Modelo.closeConnection(con4);
                                //This is the third failed time. Disable user
                                if (login_failed == 2)
                                {
                                    SqlConnection con3 = Modelo.Modelo.createConnection();
                                    Modelo.Modelo.openConnection(con3);
                                    SqlCommand disable_user = new SqlCommand(Modelo.SqlQueries.disableUser(user), con3);
                                    disable_user.ExecuteNonQuery();
                                    Modelo.Modelo.closeConnection(con3);
                                }
                            }
                        }

                        
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            return return_value;
        }

        public static string getSHA256(string input)
        {
            string hashed = null;
            byte[] inputBytes = Encoding.Unicode.GetBytes(input);
            SHA256Managed hash = new SHA256Managed();
            byte[] hashBytes = hash.ComputeHash(inputBytes);
            hashed = Convert.ToBase64String(hashBytes);
            return hashed;
        }

        private void Login_Load(object sender, EventArgs e)
        {

        }

        private void getPermissions(string username)
        {
            using (SqlConnection con2 = Modelo.Modelo.createConnection())
            {
                Modelo.Modelo.openConnection(con2);
                SqlCommand comando_get_user_id = new SqlCommand(Modelo.SqlQueries.getUserIdByUsername(username), con2);
                SqlDataReader reader = comando_get_user_id.ExecuteReader();
                List<int> roles = new List<int>();
                while (reader.Read())
                {
                    int user_id = Convert.ToInt32(reader.GetDecimal(0));
                    using (SqlConnection con = Modelo.Modelo.createConnection())
                    {
                        SqlDataAdapter us_rol_da = new SqlDataAdapter(Modelo.SqlQueries.getUserRoles(user_id), con);
                        DataTable us_rol_dt = new DataTable();
                        us_rol_da.Fill(us_rol_dt);
                        foreach (DataRow rol in us_rol_dt.Rows)
                        {
                            bool added = Convert.ToBoolean(rol.ItemArray[2]);
                            if (added)
                            {
                                int rol_id = Convert.ToInt32(rol.ItemArray[0].ToString());

                                using (SqlConnection con3 = Modelo.Modelo.createConnection())
                                {
                                    SqlDataAdapter rol_perm_da = new SqlDataAdapter(Modelo.SqlQueries.getRolePermissions(rol_id), con3);
                                    DataTable rol_perm_dt = new DataTable();
                                    rol_perm_da.Fill(rol_perm_dt);
                                    foreach (DataRow perm in rol_perm_dt.Rows)
                                    {
                                        foreach (KeyValuePair<string, int> pair in Modelo.Permissions.PermissionsDict)
                                        {
                                            if (pair.Value == Convert.ToInt32(perm.ItemArray[0].ToString()))
                                            {
                                                permisosList.Add(pair.Value);
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }



    }
}
